/*
   elf.h

   http://code.google.com/p/ccg-arm/
   ccg-arm
   Copyright 2013-6-10 supersuperguo

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

   This file defines the constances, types and structs used by the generic
   ELF standard (SVr4 GABI) with the update on 17 December 2003 draft
   (http://www.sco.com/developers/gabi/), which is the base standard of ELF
   for the ARM Architecture [AAELF], which is described at [BSAPI]
   (ABI r2.09). The [BSAPI] document is located at

   http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ihi0036b/index.html

 */

#ifndef ELF_H_
#define ELF_H_

#include "ccgdef.h"
#if _CCG_HAS_STDINT
#include <stdint.h>
#endif


/* Elf data types */
#if _CCG_HAS_STDINT
/* It is easy to define fix-length integer types by use of types in stdint.h */
typedef uint32_t Elf32_Addr;
typedef uint32_t Elf32_Off;
typedef uint16_t Elf32_Half;
typedef uint32_t Elf32_Word;
typedef int32_t  Elf32_Sword;
typedef uint64_t Elf64_Addr;
typedef uint64_t Elf64_Off;
typedef uint16_t Elf64_Half;
typedef uint32_t Elf64_Word;
typedef int32_t  Elf64_Sword;
typedef uint64_t Elf64_Xword;
typedef int64_t  Elf64_Sxword;
#elif defined(_MSC_VER)
/* VC compiler earlier than VC 2010,
 * which has no stdint.h at all!
 * Microsoft Windows (X64/IA-64) uses IL32P64 model in VC>=2005,
 * and L32P64 in VC<2005 */
typedef unsigned long   Elf32_Addr;
typedef unsigned long   Elf32_Off;
typedef unsigned short  Elf32_Half;
typedef unsigned long   Elf32_Word;
typedef long            Elf32_Sword;
typedef unsigned short  Elf64_Half;
typedef unsigned long   Elf64_Word;
typedef long            Elf64_Sword;
#if _MSC_VER >= 1400 /* VC 2005 or later */
/** We're lucky that there are unsigned 64-bit integer types. */
typedef unsigned long long Elf64_Addr;
typedef unsigned long long Elf64_Off;
typedef unsigned long long Elf64_Xword;
typedef long long       Elf64_Sxword;
#else /* earlier than VC 2005 */
/** No unsigned 64-bit integer types */
typedef __int64         Elf64_Addr;
typedef __int64         Elf64_Off;
typedef __int64         Elf64_Xword;
typedef __int64         Elf64_Sxword;
#endif
#else
#error Please define elf data types here for your compiler
#endif

/* We use enumerations types below to prettiefy the header outline */

/* e_ident[] Identification Indexes */
typedef enum ElfIdentIndexEnum {

	/** File identification */
	EI_MAG0	      = 0,

	/** File identification */
	EI_MAG1	      = 1,

	/** File identification */
	EI_MAG2       = 2,

	/** File identification */
	EI_MAG3       = 3,

	/** File class */
	EI_CLASS      = 4,

	/** Data encoding */
	EI_DATA       = 5,

	/** File version */
	EI_VERSION    = 6,

	/** Operating system/ABI identification */
	EI_OSABI      = 7,

	/** ABI version */
	EI_ABIVERSION = 8,

	/** Start of padding bytes */
	EI_PAD        = 9,

	/** Size of e_ident[] */
	EI_NIDENT     = 16

} ElfIdentIndexEnum;

/** Enumerations for e_ident[EI_MAG0] - e_ident[EI_MAG3] */
typedef enum ElfMagicEnum {

	/** e_ident[EI_MAG0] */
	ELFMAG0 = 0x7f,

	/** e_ident[EI_MAG1] */
	ELFMAG1	= 'E',

	/** e_ident[EI_MAG2] */
	ELFMAG2	= 'L',

	/** e_ident[EI_MAG3] */
	ELFMAG3	= 'F'

} ElfMagicEnum;

/** Enumerations for e_ident[EI_CLASS] */
typedef enum ElfClassEnum {

	/** Invalid class */
	ELFCLASSNONE = 0,

	/** 32-bit objects */
	ELFCLASS32   = 1,

	/** 64-bit objects */
	ELFCLASS64   = 2

} ElfClassEnum;

/** Enumerations for e_type */
typedef enum ElfTypeEnum {

	/** No file type */
	ET_NONE	= 0,

	/** Relocatable file */
	ET_REL	= 1,

	/** Executable file */
	ET_EXEC	= 2,

	/**	Shared object file */
	ET_DYN	= 3,

	/**	Core file */
	ET_CORE	= 4,

	/** Operating system-specific */
	ET_LOOS	= 0xfe00,

	/** Operating system-specific */
	ET_HIOS	= 0xfeff,

	/** Processor-specific */
	ET_LOPROC	= 0xff00,

	/** Processor-specific */
	ET_HIPROC	= 0xffff

} ElfTypeEnum;

/** Enumerations for e_machine */
typedef enum ElfMachineEnum {
	/** No machine */
	EM_NONE   = 0,

	/** AT&T WE 32100*/
	EM_M32    = 1,

	/** SPARC */
	EM_SPARC  = 2,

	/** Intel 80386 */
	EM_386    = 3,

	/** Motorola 68000 */
	EM_68K    = 4,

	/** Motorola 88000 */
	EM_88K	  = 5,

	/* 	reserved	6	Reserved for future use (was EM_486) */

	/** Intel 80860 */
	EM_860    = 7,

	/** MIPS I Architecture */
	EM_MIPS   = 8,

	/** IBM System/370 Processor */
	EM_S370   = 9,

	/** MIPS RS3000 Little-endian */
	EM_MIPS_RS3_LE = 10,

	/*	reserved	11-14	Reserved for future use */

	/** Hewlett-Packard PA-RISC */
	EM_PARISC = 15,

	/* reserved	16	Reserved for future use */

	/** Fujitsu VPP500 */
	EM_VPP500 = 17,

	/** Enhanced instruction set SPARC */
	EM_SPARC32PLUS = 18,

	/** Intel 80960 */
	EM_960    = 19,

	/** PowerPC */
	EM_PPC    = 20,

	/** 64-bit PowerPC */
	EM_PPC64  = 21,

	/** IBM System/390 Processor */
	EM_S390   = 22,

	/* reserved	23-35	Reserved for future use */

	/** NEC V800 */
	EM_V800   = 36,

	/** Fujitsu FR20 */
	EM_FR20	  = 37,

	/** TRW RH-32 */
	EM_RH32   = 38,

	/** Motorola RCE */
	EM_RCE    = 39,

	/** Advanced RISC Machines ARM */
	EM_ARM    = 40,

	/** Digital Alpha */
	EM_ALPHA  = 41,

	/** Hitachi SH */
	EM_SH     = 42,

	/** SPARC Version 9 */
	EM_SPARCV9 = 43,

	/** Siemens TriCore embedded processor */
	EM_TRICORE = 44,

	/** Argonaut RISC Core, Argonaut Technologies Inc. */
	EM_ARC    = 45,

	/** Hitachi H8/300 */
	EM_H8_300 = 46,

	/** Hitachi H8/300H */
	EM_H8_300H = 47,

	/** Hitachi H8S */
	EM_H8S    = 48,

	/** Hitachi H8/500 */
	EM_H8_500 = 49,

	/** Intel IA-64 processor architecture */
	EM_IA_64  = 50,

	/** Stanford MIPS-X */
	EM_MIPS_X = 51,

	/** Motorola ColdFire */
	EM_COLDFIRE = 52,

	/** Motorola M68HC12 */
	EM_68HC12 = 53,

	/** Fujitsu MMA Multimedia Accelerator */
	EM_MMA    = 54,

	/** Siemens PCP */
	EM_PCP    = 55,

	/** Sony nCPU embedded RISC processor */
	EM_NCPU   = 56,

	/** Denso NDR1 microprocessor */
	EM_NDR1   = 57,

	/** Motorola Star*Core processor */
	EM_STARCORE = 58,

	/** Toyota ME16 processor */
	EM_ME16   = 59,

	/** STMicroelectronics ST100 processor */
	EM_ST100  = 60,

	/** Advanced Logic Corp. TinyJ embedded processor family */
	EM_TINYJ  = 61,

	/** AMD x86-64 architecture */
	EM_X86_64 = 62,

	/** Sony DSP Processor */
	EM_PDSP   = 63,

	/** Digital Equipment Corp. PDP-10 */
	EM_PDP10  = 64,

	/** Digital Equipment Corp. PDP-11 */
	EM_PDP11  = 65,

	/** Siemens FX66 microcontroller */
	EM_FX66   = 66,

	/** STMicroelectronics ST9+ 8/16 bit microcontroller */
	EM_ST9PLUS = 67,

	/** STMicroelectronics ST7 8-bit microcontroller */
	EM_ST7    = 68,

	/** Motorola MC68HC16 Microcontroller */
	EM_68HC16 = 69,

	/** Motorola MC68HC11 Microcontroller */
	EM_68HC11 = 70,

	/** Motorola MC68HC08 Microcontroller */
	EM_68HC08 = 71,

	/** Motorola MC68HC05 Microcontroller */
	EM_68HC05 = 72,

	/** Silicon Graphics SVx */
	EM_SVX    = 73,

	/** STMicroelectronics ST19 8-bit microcontroller */
	EM_ST19   = 74,

	/** Digital VAX */
	EM_VAX    = 75,

	/** Axis Communications 32-bit embedded processor */
	EM_CRIS   = 76,

	/** Infineon Technologies 32-bit embedded processor */
	EM_JAVELIN = 77,

	/** Element 14 64-bit DSP Processor */
	EM_FIREPATH = 78,

	/** LSI Logic 16-bit DSP Processor */
	EM_ZSP    = 79,

	/** Donald Knuth's educational 64-bit processor */
	EM_MMIX	  = 80,

	/** Harvard University machine-independent object files */
	EM_HUANY  = 81,

	/** SiTera Prism */
	EM_PRISM  = 82,

	/** Atmel AVR 8-bit microcontroller */
	EM_AVR    = 83,

	/** Fujitsu FR30 */
	EM_FR30   = 84,

	/** Mitsubishi D10V */
	EM_D10V   = 85,

	/** Mitsubishi D30V */
	EM_D30V   = 86,

	/** NEC v850 */
	EM_V850   = 87,

	/** Mitsubishi M32R */
	EM_M32R   = 88,

	/** Matsushita MN10300 */
	EM_MN10300 = 89,

	/** Matsushita MN10200 */
	EM_MN10200 = 90,

	/** picoJava */
	EM_PJ      = 91,

	/** OpenRISC 32-bit embedded processor */
	EM_OPENRISC = 92,

	/** ARC Cores Tangent-A5 */
	EM_ARC_A5 = 93,

	/** Tensilica Xtensa Architecture */
	EM_XTENSA = 94,

	/** Alphamosaic VideoCore processor */
	EM_VIDEOCORE = 95,

	/** Thompson Multimedia General Purpose Processor */
	EM_TMM_GPP = 96,

	/** National Semiconductor 32000 series */
	EM_NS32K  = 97,

	/** Tenor Network TPC processor */
	EM_TPC    = 98,

	/** Trebia SNP 1000 processor */
	EM_SNP1K  = 99,

	/** STMicroelectronics (www.st.com) ST200 microcontroller */
	EM_ST200  = 100,

	/** Ubicom IP2xxx microcontroller family */
	EM_IP2K   = 101,

	/** MAX Processor */
	EM_MAX    = 102,

	/** National Semiconductor CompactRISC microprocessor */
	EM_CR     = 103,

	/** Fujitsu F2MC16 */
	EM_F2MC16 = 104,

	/** Texas Instruments embedded microcontroller msp430 */
	EM_MSP430 = 105,

	/** Analog Devices Blackfin (DSP) processor */
	EM_BLACKFIN	= 106,

	/** S1C33 Family of Seiko Epson processors */
	EM_SE_C33 = 107,

	/** Sharp embedded microprocessor */
	EM_SEP    = 108,

	/** Arca RISC Microprocessor */
	EM_ARCA	  = 109,

	/** Microprocessor series from PKU-Unity Ltd.
	 *  and MPRC of Peking University */
	EM_UNICORE = 110

} ElfMachineEnum;

/** Enumerations for e_version and e_ident[EI_VERSION] */
typedef enum ElfVersionEnum {

	/** Invalid version */
	EV_NONE	   = 0,

	/** Current version */
	EV_CURRENT = 1

} ElfVersionEnum;

/** Enumerations for e_ident[EI_DATA] */
typedef enum ElfDataEnum {

	/** Invalid data encoding */
	ELFDATANONE	= 0,

	ELFDATA2LSB	= 1,

	ELFDATA2MSB	= 2

} ElfDataEnum;

/* ELF Header */
typedef struct Elf32_Ehdr {
	/**
	 * The initial bytes mark the file as an object file and provide
	 * machine-independent data with which to decode and interpret the file's
	 * contents. Complete descriptions appear below in ``ELF Identification''.
	 */
	unsigned char   e_ident[EI_NIDENT];

	/** This member identifies the object file type. */
	Elf32_Half      e_type;

	/** This member's value specifies the required architecture for an
	 * individual file. */
	Elf32_Half      e_machine;

	Elf32_Word      e_version;
	Elf32_Addr      e_entry;
	Elf32_Off       e_phoff;
	Elf32_Off       e_shoff;
	Elf32_Word      e_flags;
	Elf32_Half      e_ehsize;
	Elf32_Half      e_phentsize;
	Elf32_Half      e_phnum;
	Elf32_Half      e_shentsize;
	Elf32_Half      e_shnum;
	Elf32_Half      e_shstrndx;
} Elf32_Ehdr;

typedef struct Elf64_Ehdr {
	/**
	 * The initial bytes mark the file as an object file and provide
	 * machine-independent data with which to decode and interpret the file's
	 * contents. Complete descriptions appear below in ``ELF Identification''.
	 */
	unsigned char   e_ident[EI_NIDENT];
	Elf64_Half      e_type;
	Elf64_Half      e_machine;
	Elf64_Word      e_version;
	Elf64_Addr      e_entry;
	Elf64_Off       e_phoff;
	Elf64_Off       e_shoff;
	Elf64_Word      e_flags;
	Elf64_Half      e_ehsize;
	Elf64_Half      e_phentsize;
	Elf64_Half      e_phnum;
	Elf64_Half      e_shentsize;
	Elf64_Half      e_shnum;
	Elf64_Half      e_shstrndx;
} Elf64_Ehdr;

#endif /* ELF_H_ */
